#ifndef __stack_H__
#define __stack_H__

#include <assert.h>
#include <stdlib.h>

#define push(stack, item) \
    { \
        typeof(*(stack)) *new_item; \
        do { \
            new_item = malloc(sizeof(*new_item)); \
            assert(new_item && "Could not allocate memory for new stack entry."); \
            new_item->value = item; \
            new_item->prev = (stack); \
            (stack) = new_item; \
        } while(0); \
    }

#define pop(stack, val) \
    { \
    typeof(*(stack)) *last; \
    last = (stack); \
    *(val) = (stack)->value; \
    (stack) = last->prev; \
    do { \
        last->value = 0; \
        last->prev = NULL; \
        free(last); \
    } while(0); \
    }

#define stack_free(stack) \
    typeof(*(stack)) *prev; \
    do { \
        for(;(stack);) { \
            prev = (stack)->prev; \
            (stack)->value = 0; \
            (stack)->prev = NULL; \
            free((stack)); \
            (stack) = prev; \
        } \
    } while(0)

#endif //__stack_H__